package main

import (
	"encoding/json"
	"fmt"
	"gitee.com/freedom_feel/gui-bos-api/common/script"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

// 日志配置
var logger = log.New(os.Stdout, "[MQ] ", log.Ldate|log.Ltime|log.Lshortfile)

const (
	queue         = "test_queue"
	consumerCount = 3 // 消费者数量：改为3个
)

func main() {
	// 1. 初始化MQ客户端（与原代码逻辑一致，仅优化错误提示）
	mq, err := script.New(script.Config{
		Host:     "59.110.50.87",
		Port:     5672,
		Username: "rabbitmq",
		Password: "eidiHY4xSKPWJjwP",
		VHost:    "/", // RabbitMQ默认VHost，不可为空
	}, queue)
	if err != nil {
		logger.Println(fmt.Printf("❌ 创建MQ客户端失败: %v\n", err))
		return
	}
	defer func() {
		// 延迟关闭MQ连接（确保所有消费者先停止）
		if err := mq.Close(); err != nil {
			logger.Println(fmt.Printf("⚠️  关闭MQ连接时出错: %v\n", err))
		}
	}()

	// 2. 创建生产者并发送消息（与原代码完全一致，无修改）
	producer, err := mq.NewProducer()
	if err != nil {
		logger.Println(fmt.Printf("❌ 创建生产者失败: %v\n", err))
		return
	}

	// 构造用户注册消息
	userInfo := struct {
		Username string `json:"username"`
		Email    string `json:"email"`
		Age      int    `json:"age"`
	}{
		Username: "zhangsan",
		Email:    "zhangsan@example.com",
		Age:      25,
	}
	userJSON, err := json.Marshal(userInfo)
	if err != nil {
		logger.Println(fmt.Printf("❌ 数据序列化失败: %v\n", err))
		return
	}
	msg := script.Message{
		Body: userJSON,
		Headers: map[string]interface{}{
			"type":      "user_register",
			"priority":  1,
			"timestamp": time.Now().Unix(),
		},
	}
	if err := producer.Publish(msg); err != nil {
		logger.Println(fmt.Printf("❌ 发送消息失败: %v\n", err))
		return
	}
	logger.Println(fmt.Println("✅ 消息发送成功，等待3个消费者处理..."))

	// 3. 核心修改：创建3个独立消费者
	// 3.1 定义消费者退出信号（用于统一控制所有消费者停止）
	consumers := make([]script.Consumer, 0, consumerCount) // 存储3个消费者实例
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // 监听Ctrl+C、程序终止信号

	// 3.2 循环创建并启动3个消费者
	for i := 1; i <= consumerCount; i++ {
		// 创建单个消费者实例（每个消费者独立，由MQ客户端分配不同通道）
		consumer, err := mq.NewConsumer(queue)
		if err != nil {
			logger.Println(fmt.Printf("❌ 创建消费者%d失败: %v\n", i, err))
			// 若某个消费者创建失败，先停止已创建的消费者，避免资源泄漏
			for _, c := range consumers {
				_ = c.Stop()
			}
			return
		}
		consumers = append(consumers, consumer) // 加入消费者列表，便于后续统一停止

		// 启动当前消费者（绑定带编号的处理函数，区分不同消费者）
		consumerID := i // 闭包中需捕获独立变量，避免循环变量覆盖
		if err := consumer.Start(func(msg script.Message) bool {
			// 消息处理逻辑（与原代码一致，仅增加【消费者ID】标识）
			var userInfo struct {
				Username string `json:"username"`
				Email    string `json:"email"`
				Age      int    `json:"age"`
			}
			if err := json.Unmarshal(msg.Body, &userInfo); err != nil {
				logger.Println(fmt.Printf("⚠️  消费者%d解析消息失败: %v\n", consumerID, err))
				return true // 解析失败仍继续消费其他消息
			}

			// 提取消息头信息（增加类型断言安全判断）
			msgType, _ := msg.Headers["type"].(string)
			priority, ok := msg.Headers["priority"].(int)
			if !ok {
				priority = 0 // 若优先级不存在，默认设为0
			}

			// 打印消费日志（明确标注哪个消费者处理了消息）
			logger.Println(fmt.Printf("✅ 消费者%d收到[%s]消息: 用户%s注册，邮箱%s，优先级%d\n",
				consumerID, msgType, userInfo.Username, userInfo.Email, priority))
			return true // 返回true表示继续消费，返回false则停止当前消费者
		}); err != nil {
			logger.Println(fmt.Printf("❌ 启动消费者%d失败: %v\n", consumerID, err))
			// 启动失败时，停止已创建的所有消费者
			for _, c := range consumers {
				_ = c.Stop()
			}
			return
		}

		logger.Println(fmt.Printf("📌 消费者%d已启动，开始监听队列%s\n", consumerID, queue))
	}

	// 4. 主线程阻塞：等待系统退出信号（Ctrl+C或kill命令）
	<-sigChan
	logger.Println(fmt.Println("\n📢 收到退出信号，正在停止所有消费者..."))

	// 5. 优雅停止所有消费者（遍历消费者列表，逐个停止）
	for i, consumer := range consumers {
		if err := consumer.Stop(); err != nil {
			logger.Println(fmt.Printf("⚠️  停止消费者%d时出错: %v\n", i+1, err))
		} else {
			logger.Println(fmt.Printf("✅ 消费者%d已成功停止\n", i+1))
		}
	}

	logger.Println(fmt.Println("📌 所有消费者已停止，程序退出"))
}
